package book;

import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.List;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

import screen.BookScreen;
import screen.BooksBrowser;
import screen.SplashScreen;
import state.State;
import data.PhraseMark;

public class Book extends MIDlet {

	private static Book instance;

	private BookReader bookReader;
	private BookScreen bookScreen;
	private PhraseMark phraseMark;
	private SpeedManager speedManager;
	private State state;

	private Timer displayTimer;

	private LightManager lightManager;

	private SplashScreen splash;

	public Book() {
		if (instance == null) {
			instance = this;
		}
		state = new State(State.IDLE);
	}

	protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
		try {
			phraseMark.save();
		} catch (IOException e) {
			e.printStackTrace();
		}
		notifyDestroyed();
	}

	protected void pauseApp() {

	}

	protected void startApp() throws MIDletStateChangeException {
		try {
			lightManager = new LightManagerImpl();
		} catch (IOException e) {
			e.printStackTrace();
		}
		BooksBrowser browser = new BooksBrowser();
		List booksList = browser.getListOfBooks();
		setDisplay(booksList);
		
	}
	
	public void openBook() {
		splash = new SplashScreen(this);
		setDisplay(splash);
		splash.doFadingSplash();
	}

	public void readNext() {
		if (!bookReader.isDone()) {
			try {
				pauseReading();
				String nextPhrase = bookReader.getNextPhrase();
				phraseMark.increment(1);
				bookScreen.displayPhrase(nextPhrase);
				int duration = speedManager.computeDuration(nextPhrase);
				sheduleNewDisplayTask(duration);
			} catch (IOException e) {
				Book.debugAlert("Error while reading.");
			}
		} 
	}
	
	public void buttonPausePushed() {
		if (state.equals(State.IN_PAUSE)) {
//			setDisplay(bookScreen);
			readNext();
			state.remove(State.IN_PAUSE);
		} else {
//			setDisplay(splash);
//			splash.doCasualSplash();
			pauseReading();
			state.add(State.IN_PAUSE);
		}
		bookScreen.repaint();
	}

	private void setDisplay(Displayable d) {
		Display.getDisplay(this).setCurrent(d);
	}

	private void pauseReading() {
		if (displayTimer != null) {
			displayTimer.cancel();
		}
	}

	private void debugAlert2(String message) {
		Alert alert = new Alert("Debug", message, null, AlertType.INFO);
		setDisplay(alert);
	}

	public static void debugAlert(String message) {
		instance.debugAlert2(message);
	}

	private class DisplayTask extends TimerTask {

		public void run() {
			String nextPhrase;
			try {
				nextPhrase = bookReader.getNextPhrase();
				phraseMark.increment(1);
				bookScreen.displayPhrase(nextPhrase);
				int duration = speedManager.computeDuration(nextPhrase);
				sheduleNewDisplayTask(duration);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public void sheduleNewDisplayTask(int duration) {
		displayTimer = new Timer();
		displayTimer.schedule(new DisplayTask(), duration);
	}

	public void eventDownPressed() {
		readNext();
	}

	public void eventReadyToGo() {
		setDisplay(bookScreen);
	}

	public void eventNewPhraseIndexSelected(int NewPhraseIndex) {
		phraseMark.setMark(NewPhraseIndex);
		try {
			phraseMark.save();
		} catch (IOException e) {
			e.printStackTrace();
		}
		stopReading();
		startReading();
	}

	private void stopReading() {
		bookReader.stopReading();
	}

	public void startReading() {
			try {
				speedManager = new SpeedManagerImpl();
				phraseMark = new PhraseMark();
				bookScreen = new BookScreen(this);
				// bookScreen.addCommand(pause);
				setDisplay(bookScreen);
	
				bookReader = new BookReader(this);
				String firstPhrase = bookReader.getNextPhrase();
				int phraseIndex = phraseMark.getMark();
				for (int i = 0; (i < phraseIndex) && (bookReader.hasNext()); i++) {
					firstPhrase = bookReader.getNextPhrase();
				}
				if (bookReader.hasNext()) {					
					bookScreen.displayPhrase(firstPhrase);
					int duration = speedManager.computeDuration(firstPhrase);
					sheduleNewDisplayTask(duration);
				} else {
					debugAlert("End of book reached");
					phraseMark.setMark(0);
					startReading();
				}
			} catch (IOException e) {
				debugAlert("IO Exception");
			}
	}

	public void eventLeftPressed() {
		speedManager.decreaseSpeed();
		bookScreen.showSpeed();
	}

	public void eventRightPressed() {
		speedManager.increaseSpeed();
		bookScreen.showSpeed();
	}
	
	public void eventFourPressed() {
		lightManager.decreaseLight();
	}

	public void eventOnePressed() {
		lightManager.increaseLight();
	}

	public int getSpeed() {
		return speedManager.getSpeed();
	}

	public void eventFivePressed() {
		state.add(State.PAGE_SELECTION);
		pauseReading();
		bookScreen.computePage(phraseMark.getMark());
		bookScreen.computeCommands();
		bookScreen.repaint();
	}
	
	public static State getState() {
		return instance.state;
	}

	public static Book getInstance() {
		return instance;
	}

	public void eventDestroy() {
		try {
			destroyApp(false);
		} catch (MIDletStateChangeException e) {
			e.printStackTrace();
		}
	}

	public void eventBackToReading() {
		readNext();
	}
}
